# Ruby 单行注释
puts '# Ruby 单行注释的标识符'
=begin
Ruby 多行注释
=end
BEGIN {
    puts 'Ruby 文件执行之前被调用'
    puts '--------------------'
}
END {
    puts '--------------------'
    puts 'Ruby 文件执行之后被调用'
}
## 1、变量
### 1. 判断变量的类型
variable='' # 声明变量
puts variable.class # String【Integer、Float、String、Array、Hash、NilClass、TrueClass、FalseClass】
### 2. 判断变量是否未定义
# var_string = nil # 定义 nil 也是定义了变量
is_defined = defined?(var_string).nil?
puts is_defined # true 表示未定义｜false 表示已定义
## 2、字符串
### 1. 单行字符串
var_string = '声明单行字符串'
var_string = "#{var_string}，双引号中可以解析变量"
puts var_string
### 2. 多行字符串，解析变量
var_string = 'Here Document 中可以解析变量'
here_document = <<EOF
这是多行字符串声明方法
#{var_string}
EOF
puts here_document
### 3. 多行字符串，不解析变量
var_string = '使用 \'EOF\' Here Documnet 不解析变量'
here_document = <<'EOF'
使用 'EOF' Here Documnet 不解析变量
#{var_string}
EOF
puts here_document
## 3、数组
### 1. 声明空数组
var_array = []
var_array[1] = 'a'
puts var_array
### 2. 获取数组长度
var_array_size = var_array.size
puts "数组的长度为：#{var_array_size}" # 2
var_array_length = var_array.length
puts "数组的长度为：#{var_array_length}" # 2
### 3. 定义一个长度为 n=10 的数组
n = 10
var_array = Array.new(n)
puts "数组的长度为：#{var_array.length}"
### 4. 数组简单操作
#### 1. 向数组中添加一个值[添加元素到数组结尾]
# var_array.push(10);
var_array << 10;
puts "添加元素到数组结尾后的额数组长度为：#{var_array.length}" # 11
#### 2. 删除数组某一个值
var_array.delete_at(9);
puts "删除数组某一个值后的数组长度为：#{var_array.length}" # 10
#### 3. 移除数组第一个值
var_array.delete_at(0);
puts "移除数组第一个值后的额数组长度为：#{var_array.length}" # 9
var_array_first_value = var_array.shift()
puts "移除数组第一个值后的额数组长度为：#{var_array.length}" # 8
#### 4. 移除数组最后一个值
var_array_last_value = var_array.pop();
puts "删除数组最后一个值为：#{var_array_last_value}" # 10
#### 5. 添加元素到数组开头
var_array = [0].concat(var_array)
puts var_array.inspect # [0, nil, nil, nil, nil, nil, nil, nil]
#### 6. 数组迭代
##### 1. 键值
var_array.each_with_index do |value,key|
    var_array[key] = value.nil? ? key : value
end
puts var_array.inspect # [0, 1, 2, 3, 4, 5, 6, 7]
##### 2. 只能迭代出值
var_array.each do |value|
    puts "current item is #{value}"
end
#### 7. 数组克隆【Ruby 中数组为对象，所以赋值为引用赋值，所以当需要复制数组时，需要克隆复制】
var_array2 = var_array
puts var_array2.inspect # [0, 1, 2, 3, 4, 5, 6, 7]
var_array << 10
puts var_array2.inspect # [0, 1, 2, 3, 4, 5, 6, 7, 10]
var_array3 = var_array.clone
puts var_array3.inspect # [0, 1, 2, 3, 4, 5, 6, 7, 10]
var_array << 100
puts var_array3.inspect # [0, 1, 2, 3, 4, 5, 6, 7, 10]
puts var_array.inspect # [0, 1, 2, 3, 4, 5, 6, 7, 10, 100]

## 4、哈希
### 1. 定义一个空哈希
var_hash = {}
puts var_hash # {}
var_hash[:title] = '标题'
puts var_hash[:title] # 标题
### 2. 获取哈希长度
puts "哈希的长度为：#{var_hash.length}" # 1
### 3. 哈希简单操作
#### 1. 向哈希中添加一个值[添加元素到哈希结尾]
var_hash[:descript] = '描述'
#### 2. 删除哈希某一个值
var_hash.delete(:descript)
puts var_hash # {:title=>"标题"}
#### 3. 移除哈希第一个值
var_hash[:descript] = '移除哈希第一个值'
puts var_hash # {:title=>"标题", :descript=>"移除哈希第一个值"}
var_hash_first_value = var_hash.shift(); # 返回 [键,值] 或者 键,值
puts var_hash # {:descript=>"移除哈希第一个值"}
puts var_hash_first_value.inspect
#### 4. 移除哈希最后一个值
#### 5. 添加元素到哈希开头
#### 6. 哈希迭代
var_hash = {}
var_hash[:title] = 'hash.each'
var_hash[:descript] = '哈希迭代'
var_hash.each do |key,value|
    puts "current #{key} is #{value}"
end

## 5、类和对象
### 1. 定义一个类
class Language
    # 构造方法
    def initialize
        puts '实例化了一个类'
    end
    # 常量属性
    TITLE = '语言'
    # 静态属性
    @@description = '学习语言的特性'
    # 实例属性
    @name='Ruby'
    # 静态方法
    def self.get_desc
        @@description
    end
    # 实例方法
    def set_name(name)
        @name=name
    end
    def get_name
        @name
    end
end

### 2. 继承一个类
class Lan < Language
    def description
        @@description
    end
end

### 3. 类和对象的操作
#### 1、实例化一个类
language = Language.new
#### 2、调用常量属性
result = Language::TITLE
puts "调用常量属性结果为：#{result}"
#### 3、调用静态属性：无法直接调用静态属性
# result = Language.description # 报错
#### 4、调用静态方法
result = Language.get_desc
puts "调用静态方法结果为：#{result}"
#### 5、调用实例属性：无法直接调用实例属性
# result = language.name # 报错
#### 6、调用实例方法
language.set_name('PHP')
result = language.get_name
puts "调用实例方法后输出实例属性为：#{result}"
#### 7、子类调用静态属性
result = Lan.new.description
puts "子类实例后在实例方法中静态属性结果为：#{result}"

### 4. 访问控制
class English < Language
    @cn_name
    # 声明实例变量的控制方法
    attr_accessor :come_from
    # public 默认控制
    public def index
        get_cn_name()
    end
    # protected 访问控制
    protected def get_cn_name()
        puts @cn_name
    end
    # private 访问控制
    def set_cn_name(cn_name)
        @cn_name=cn_name
    end
    private :set_cn_name
    # 构造方法
    def initialize(cn_name = nil)
        if !cn_name
            cn_name = '英语'
        end
        set_cn_name(cn_name)
    end
end
class AmericanEnglish < English
    def getCnName()
        get_cn_name() # 可以访问
    end
    def setCnName(cn_name)
        set_cn_name(cn_name) # 可以访问
    end
end
#### 1. 验证 attr_accessor 的作用
english = English.new
english.come_from=('The UK')
result = english.come_from()
puts "调用 attr_accessor 定义的变量结果为：#{result}"
#### 2. 验证父类中 3P 的作用
english.index() # 可以访问
# english.get_cn_name # 无法访问：protected method `get_cn_name' called for
# english.set_cn_name('英式英语') # 无法访问：private method `set_cn_name' called for
#### 3. 验证子类中 3P 的作用
american_english = AmericanEnglish.new('美式英语')
american_english.getCnName() # 可以访问
american_english.setCnName('美式') # 可以访问
american_english.getCnName() # 可以访问
